/*	This file is part of AstroAttack.
*
*	AstroAttack is free software; you can redistribute it and/or modify
*	it under the terms of the GNU General Public License as published by
*	the Free Software Foundation; either version 2 of the License, or
*	(at your option) any later version.
*	
*	AstroAttack is distributed in the hope that it will be useful,
*	but WITHOUT ANY WARRANTY; without even the implied warranty of
*	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*	GNU General Public License for more details.
*	
*	You should have received a copy of the GNU General Public License
*	along with AstroAttack; if not, write to the Free Software
*	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*	
*	$Id: ShipController.java 64 2007-01-06 03:30:23Z xdracox $
*/

/**	The AstroAttack package contains all the classes that belong to the
*	AstroAttack program.
*/
package AstroAttack;

import java.util.ArrayList;

import java.awt.Component;

import java.awt.geom.Point2D;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

/**	Controls a human player (a ship). */
public class ShipController extends KeyAdapter implements Controller
{
	/**	The single instance of the class. */
	private static ShipController m_ref;
	
	/**	This method returns the instance or initializes if it hasn't been
	*	initialized.
    *	@return	the instance of AlienController
	*/
	public static ShipController getShipController()
	{
		if ( m_ref == null )
			m_ref = new ShipController(null);
		return m_ref;
	}
	
	/**	Speed the ship moves at */
	public static final int SPEED = 10;
	
	/**	The Entity to control. */
	private Ship m_ship;
	private BulletController m_bc;
	private int frames;
	private boolean m_spaceHeld;
	private boolean keys[];
	
	public ShipController(Ship ship)
	{
		m_ref = this;
		m_ship = ship;
		m_bc = BulletController.getBulletController();
		frames = 0;
		m_spaceHeld = false;
		keys = new boolean[4];
	}
	
	public void control()
	{
		// My opinion is that Engine should have to call control() for all the 
		// Controllers, but never call a move() method
		Point2D oldPoint = m_ship.getPoint();
		double newX = oldPoint.getX();
		double newY = oldPoint.getY();
		
		if ( keys[0] )
			newY -= SPEED;
		if ( keys[1] )
			newX += SPEED;
		if ( keys[2] )
			newY += SPEED;
		if ( keys[3] )
			newX -= SPEED;
		
		m_ship.setPoint(new Point2D.Double(newX, newY));
		
		m_ship.move();
		
		++frames;
		if ( frames == Engine.getEngine().getCanvasRate() * 100 )
			frames = 1;
	}
	
	public ArrayList<Entity> getEntities()
	{
		ArrayList<Entity> ret = new ArrayList<Entity>();
		ret.add(m_ship);
		return ret;
	}
	
	public void keyPressed(KeyEvent e)
	{
		switch ( e.getKeyCode() )
		{
			case KeyEvent.VK_UP:
				keys[0] = true;
				break;
			case KeyEvent.VK_RIGHT:
				keys[1] = true;
				break;
			case KeyEvent.VK_DOWN:
				keys[2] = true;
				break;
			case KeyEvent.VK_LEFT:
				keys[3] = true;
				break;
			case KeyEvent.VK_SPACE:
				WorldManager wm = WorldManager.getManager();
				// if the space button is being held down, only shoot once per second
				if ( frames % Engine.getEngine().getCanvasRate() == 0 || !m_spaceHeld )
					m_bc.addBullet(wm.createBullet(wm.getShipBullet(), (Point2D)m_ship.getPoint().clone(), 1, 90), 1);
				m_spaceHeld = true;
				break;
			default:
		}
	}
	
	public void keyReleased(KeyEvent e)
	{
		switch ( e.getKeyCode() )
		{
			case KeyEvent.VK_UP:
				keys[0] = false;
				break;
			case KeyEvent.VK_RIGHT:
				keys[1] = false;
				break;
			case KeyEvent.VK_DOWN:
				keys[2] = false;
				break;
			case KeyEvent.VK_LEFT:
				keys[3] = false;
				break;
			case KeyEvent.VK_SPACE:
				m_spaceHeld = false;
				break;
			default:
		}
	}
	
	public void keyTyped(KeyEvent e)
	{
	}
}
